
static int cursor = 0;

static inline void
outb(unsigned short port, unsigned char value)
{
     asm("outb %1,%0;" : "=d"(port) : "r"(value));
}

static void move_cursor()
{
     outb(0x3d4, 14);
     outb(0x3d5, cursor>>8);
     outb(0x3d4, 15);
     outb(0x3d5, cursor);

     return;
}

void delay()
{
     int i, j, k;

     for (i = 0; i < 10000; ++i)
     {
	  for ( j = 0; j < 10; ++j)
	  {
	       for (k = 0; k < 1; ++k)
	       {
		    ;
	       }
	  }
     }
}
void putc(char c)
{
     switch(c)
     {
     case '\n':
     {
	  cursor += (80 - cursor%80);
	  break;
     }

     case '\t':
     {
	  cursor += 4;
	  break;
     }
     default:
     {
	  char* des = (char*) (0xc00b8000 + cursor*2);
	  *des = c;
	  cursor++;
     }
     }
     if (cursor >= 80*25)
     {
	  int i, j;
	  for (i = 0; i < 24; ++i)
	  {
	       for (j = 0; j < 160/sizeof(int); ++j)
	       {
		    *(int*)(0xc00b8000 + 160*i + 4*j) =
			 *(int*)(0xc00b8000 + 160*(i + 1) + 4*j);
	       }
	  }
	  for (i = 0; i < 80; ++i)
	  {
	       *(short*) (0xc00b8000 + 80*24*2 + 2*i) = 0x0f20;
	  }
	  cursor = 80*24;
     }
     move_cursor();
}

void puts(char* str)
{
     while(*str)
     {
	  putc(*str++);
     }
     return;
}

void clear()
{
     int i = 0;
     while (i < 80*25)
     {
	  *(short*)(0xc00b8000 + i*2) = 0x0f20;
	  i++;
     }
     cursor = 0;
     move_cursor();
     
     return;
}

void disp_hex(unsigned value)
{
     static char table[] = "0123456789ABCDEF";
     //puts("0x");
     int i;
     for (i = 7; i >= 0; --i)
     {
	  putc(table[(value >> 4*i) & 0x0000000f]);
     }

}

/* bugs: max negtive integer cannot display */
void disp_int(int value)
{
     unsigned tmp = value;
     
     if (value < 0)
     {
	  putc('-');
	  tmp = ~(value - 1);
     }

     /* max length of int is 10 */
     char buf[10] = {0};
     int i = 0;
     
     do
     {
	  buf[i++] = (tmp % 10) + '0';
     } while (tmp /= 10);

     while(i--)
     {
	  putc(buf[i]);
     }
     
     return;
}


